using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Logging;

using NUnit.Framework;

namespace Sandia.MVCFramework.Test
{
    /// <summary>
    /// Configuration for exception handling is defined in App.config file,
    /// which should be edited using the Microsoft Enterprise Library
    /// Configuration tool
    /// </summary>
    [TestFixture]
    public class ExceptionHandlingTests : FailOnErrorLoggingTestFixture
    {
        private const string LOG_FILE = "exceptiontest.log";

        [Test]
        public void ExceptionHandlingTest()
        {
            // Erase existing log (if it exists)
            if (File.Exists(LOG_FILE))
            {
                File.Delete(LOG_FILE);
            }                       
           
            // Throw a generic exception, which should generate
            // a log entry
            try
            {
                throw new System.Exception("This is a test");
            }
            catch (Exception e)
            {
                bool rethrow = ExceptionPolicy.HandleException(e, "Global Policy");
                if (rethrow)
                {
                    throw;
                }

                Assert.IsFalse(rethrow);
            }

            // Throw an application exception, which should generate
            // both a log entry and cause a new NotSupportedException to be thrown
            try
            {
                try
                {
                    throw new System.ApplicationException("Application exception test");
                }
                catch (Exception e)
                {
                    bool rethrow = ExceptionPolicy.HandleException(e, "Notify Policy");
                    if (rethrow)
                    {
                        throw;
                    }

                    Assert.IsFalse(rethrow);
                }
            }
            catch (Exception e)
            {
                Assert.IsTrue(e is System.NotSupportedException);
                Assert.IsTrue(e.Message.StartsWith("An error occurred while processing your request. Please contact technical support using the following identifier: "));
            }

            // Make sure right stuff was written out to log flat file
            // NOTE: Can't directly read LOG_FILE, as it is still in use
            // by the logger, so need to make a copy of it to read
            File.Copy(LOG_FILE, LOG_FILE + ".tmp", true);
            StreamReader reader = new StreamReader(LOG_FILE + ".tmp");
            string line = reader.ReadLine();
            Assert.AreEqual(line, "----------------header------------------------");
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Timestamp: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Message: HandlingInstanceID: "));
            line = reader.ReadLine();
            Assert.AreEqual(line, "An exception of type 'System.Exception' occurred and was caught.");
            line = reader.ReadLine();
            Assert.AreEqual(line, "----------------------------------------------------------------");
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Type : System.Exception, mscorlib, Version="));
            line = reader.ReadLine();
            Assert.AreEqual(line, "Message : This is a test");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Source : Sandia.MVCFramework.Test");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Help link : ");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Data : System.Collections.ListDictionaryInternal");
            line = reader.ReadLine();
            Assert.AreEqual(line, "TargetSite : Void ExceptionHandlingTest()");
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Stack Trace :    at Sandia.MVCFramework.Test.ExceptionHandlingTests.ExceptionHandlingTest() in "));
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Additional Info:"));
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("MachineName : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("TimeStamp : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version="));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("AppDomainName : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("ThreadIdentity : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("WindowsIdentity : "));
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.AreEqual(line, "Category: Debug");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Priority: 0");
            line = reader.ReadLine();
            Assert.AreEqual(line, "EventId: 100");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Severity: Error");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Title:Quick Start Application Exception");
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Machine: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Application Domain: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Process Id: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Process Name: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Win32 Thread Id: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Thread Name: "));
            line = reader.ReadLine();
            Assert.AreEqual(line, "Extended Properties: ");
            line = reader.ReadLine();
            Assert.AreEqual(line, "----------------footer------------------------");

            line = reader.ReadLine();
            Assert.AreEqual(line, "----------------header------------------------");
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Timestamp: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Message: HandlingInstanceID: "));
            line = reader.ReadLine();
            Assert.AreEqual(line, "An exception of type 'System.ApplicationException' occurred and was caught.");
            line = reader.ReadLine();
            Assert.AreEqual(line, "---------------------------------------------------------------------------");
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Type : System.ApplicationException, mscorlib, Version="));
            line = reader.ReadLine();
            Assert.AreEqual(line, "Message : Application exception test");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Source : Sandia.MVCFramework.Test");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Help link : ");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Data : System.Collections.ListDictionaryInternal");
            line = reader.ReadLine();
            Assert.AreEqual(line, "TargetSite : Void ExceptionHandlingTest()");
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Stack Trace :    at Sandia.MVCFramework.Test.ExceptionHandlingTests.ExceptionHandlingTest() in "));
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Additional Info:"));
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("MachineName : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("TimeStamp : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version="));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("AppDomainName : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("ThreadIdentity : "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("WindowsIdentity : "));
            line = reader.ReadLine();
            line = reader.ReadLine();
            Assert.AreEqual(line, "Category: Debug");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Priority: 0");
            line = reader.ReadLine();
            Assert.AreEqual(line, "EventId: 100");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Severity: Error");
            line = reader.ReadLine();
            Assert.AreEqual(line, "Title:Enterprise Library Exception Handling");
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Machine: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Application Domain: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Process Id: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Process Name: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Win32 Thread Id: "));
            line = reader.ReadLine();
            Assert.IsTrue(line.StartsWith("Thread Name: "));
            line = reader.ReadLine();
            Assert.AreEqual(line, "Extended Properties: ");
            line = reader.ReadLine();
            Assert.AreEqual(line, "----------------footer------------------------");

            reader.Close();

            if (File.Exists(LOG_FILE + ".tmp"))
            {
                File.Delete(LOG_FILE + ".tmp");
            }
        }
    }
}
